//
// Created by QU on 2024/4/10.
//
#include <iostream>
#include <list>

#include <vector>
// vector
#include <functional>
// bind() / ref()
#include <iterator>

#include <algorithm>

using namespace std;
using namespace std::placeholders;

int main(int argc, [[maybe_unused]] const char *argv[]) {
    vector<string> vs{"aquawius", "this", "hahaha", "lambda", "testing", "returned", "type", "functionly"};
    list<string> ls{"aquawius", "this", "hahaha", "lambda", "testing", "returned", "type", "functionly"};

    /**
     * ·插入迭代器( insert iterator ) : 这些迭代器被绑定到一个容器上，可用来向容器插入 元素。
     * ·流迭代器( stream iterator ) : 这些迭代器被绑定到输入或输出流上，可用来遍历所 关联的RO 流。
     * ·反向迭代器( reverse iterator ) : 这些迭代器向后而不是向前移动。除了 forward_list 之外的标准库容器都有反向迭代器。
     * ·移动迭代器( move iterator ) : 这些专用的迭代器不是拷贝其中的元素，而是移动它们。
     */

    // 插入迭代器
    /**
     * 只有在容器支持push_front的情况下，我们才可以使用 front_inserter.
       类似的，只有在容器支持push_back 的情况下，我们才能使用 back_inserter 。
     */
    // vector 并不支持 push_front.

    list<string> list2;
    auto frontIter = front_inserter(list2);
    unique_copy(ls.begin(), ls.end(), frontIter);
    copy(ls.begin(), ls.end(), frontIter);
    // 本质上调用的是list.front_push();

    for_each(list2.begin(), list2.end(), [](auto item) { cout << item << " "; });

    //////////////////////////////////////////////////////////////////////////////////////////////////

    vector<int> vs_int;
    istream_iterator<int> int_it(std::cin);
    istream_iterator<int> eof;
    // 默认构造返回的iterator是eof, 还是说得到一个空的值和eof相等.
    /**
     * istream_iterator<int> eof; 是一个默认构造的 istream_iterator<int>，它代表着流的结束（end-of-file）。
     * 在大多数情况下，它将等效于输入流的结束符号（EOF）。
     * istream_iterator 是一个迭代器，它从输入流中读取数据并生成对应的值。
     * 当输入流结束时，istream_iterator 会自动变为 end-of-stream（EOF）状态，这个状态和你构造的 eof 迭代器是一样的。
     * 因此，int_it != eof 这个条件就相当于在检查输入流是否结束。
     * 在你的 while 循环中，int_it 从输入流中读取整数并将其加入到 vs_int 向量中，直到输入流结束。
     * 总之，istream_iterator<int> eof; 默认构造得到的 eof 迭代器表示输入流的结束，因此在 while 循环中，int_it != eof 条件检查输入流是否结束。
     */
    while (int_it != eof) {
        vs_int.push_back(*int_it++);
    }
    // 读字符时，std::istream_iterator 默认跳过空白（除非用 std::noskipws 或等价物禁用，而 std::istreambuf_iterator 不跳过。
    // 另外，std::istreambuf_iterator 更有效率，因为它避免对每个字符构造并析构一次 sentry 对象的开销。

    ostream_iterator<int> out_iter(cout, " ");
    /*
     * ostream_iterator<T> out (os) ; out将类型为 T 的值写到输出流 OS 中
     * ostream_iterator<T> out (os , d ); out将类型为 T 的值写到输出流 OS 中，每个值后而都输出一个d。d指向一个空字符结尾的字符数组
     *
     * *out , ++out , out++这些运算符是存在的，但不对 out做任何事情 。 每个运算符都返回 out
     */

    for (const auto &item: vs_int) {
        *out_iter++ = item;
    }
    cout << endl;

    /*
     * 运算符*和++实际上对ostream_iterator对象不做任何事情，因此忽略它们对我们的程序没有任何影响。
     * 但是，推荐第一种形式。在这种写法中，流迭代器的使用与其他迭代器的使用保持一致。a
     * 如果想将此循环改为操作其他迭代器类型，修改起来非常容易。而且，对于读者来说，此循环的行为也更为清晰。
     * 可以通过调用copy来打印vec中的元素，这比编写循环更为简单：
     */
    copy(vs_int.begin(),vs_int.end(),out_iter);
    cout<< endl;

}